/*
 * $Id: endian.c,v 1.5 2005-12-27 16:22:39 bacon Exp $
 */

#include <xp/bas/endian.h>

xp_bool_t xp_is_endian_big (void)
{
#if defined(XP_ENDIAN_BIG)
	return xp_true;
#elif defined(XP_ENDIAN_LITTLE)
	return xp_false;
#else
	short one = 1;
	char* c = (char*)&one;
	return *c == 0;
#endif
}

xp_bool_t xp_is_endian_little (void)
{
#if defined(XP_ENDIAN_BIG)
	return xp_false;
#elif defined(XP_ENDIAN_LITTLE)
	return xp_true;
#else
	short one = 1;
	char* c = (char*)&one;
	return *c != 0;
#endif
}

xp_uint16_t xp_ntoh16 (xp_uint16_t x)
{
#if defined(XP_ENDIAN_BIG)
	return x;
#elif defined(XP_ENDIAN_LITTLE)
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint16_t)((c[0] << 8) | c[1]);
#else
	if (xp_is_endian_big()) return x;
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint16_t)((c[0] << 8) | c[1]);
#endif
}

xp_uint16_t xp_hton16 (xp_uint16_t x)
{
#if defined(XP_ENDIAN_BIG)
	return x;
#elif defined(XP_ENDIAN_LITTLE)
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint16_t)((c[0] << 8) | c[1]);
#else
	if (xp_is_endian_big()) return x;
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint16_t)((c[0] << 8) | c[1]);
#endif
}

xp_uint32_t xp_ntoh32 (xp_uint32_t x)
{
#if defined(XP_ENDIAN_BIG)
	return x;
#elif defined(XP_ENDIAN_LITTLE)
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint32_t)((c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]);
#else
	if (xp_is_endian_big()) return x;
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint32_t)((c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]);
#endif
}

xp_uint32_t xp_hton32 (xp_uint32_t x)
{
#if defined(XP_ENDIAN_BIG)
	return x;
#elif defined(XP_ENDIAN_LITTLE)
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint32_t)((c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]);
#else
	if (xp_is_endian_big()) return x;
	xp_byte_t* c = (xp_byte_t*)&x;
	return (xp_uint32_t)((c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]);
#endif
}
